from typing import Optional, List
from sqlalchemy.orm import Session
from sqlalchemy import or_

from app.models.user import User
from app.models.role import Role
from app.schemas.user import UserCreate, UserUpdate
from app.core.security import get_password_hash

class UserService:
    """用户服务类"""
    
    def __init__(self, db: Session):
        self.db = db
    
    def get(self, user_id: int) -> Optional[User]:
        """根据ID获取用户"""
        return self.db.query(User).filter(User.id == user_id).first()
    
    def get_by_username(self, username: str) -> Optional[User]:
        """根据用户名获取用户"""
        return self.db.query(User).filter(User.username == username).first()
    
    def get_by_email(self, email: str) -> Optional[User]:
        """根据邮箱获取用户"""
        return self.db.query(User).filter(User.email == email).first()
    
    def get_by_username_or_email(self, identifier: str) -> Optional[User]:
        """根据用户名或邮箱获取用户"""
        return self.db.query(User).filter(
            or_(User.username == identifier, User.email == identifier)
        ).first()
    
    def get_multi(
        self, 
        skip: int = 0, 
        limit: int = 100,
        is_active: Optional[bool] = None,
        search: Optional[str] = None
    ) -> List[User]:
        """获取用户列表"""
        query = self.db.query(User)
        
        if is_active is not None:
            query = query.filter(User.is_active == is_active)
        
        if search:
            query = query.filter(
                or_(
                    User.username.contains(search),
                    User.email.contains(search),
                    User.full_name.contains(search)
                )
            )
        
        return query.offset(skip).limit(limit).all()
    
    def create(self, user_data: UserCreate) -> User:
        """创建用户"""
        # 创建用户对象
        db_user = User(
            username=user_data.username,
            email=user_data.email,
            full_name=user_data.full_name,
            phone=user_data.phone,
            department=user_data.department,
            position=user_data.position,
            avatar=user_data.avatar,
            hashed_password=get_password_hash(user_data.password),
            is_active=True,
            is_verified=False
        )
        
        # 添加角色
        if user_data.role_ids:
            roles = self.db.query(Role).filter(Role.id.in_(user_data.role_ids)).all()
            db_user.roles = roles
        
        self.db.add(db_user)
        self.db.commit()
        self.db.refresh(db_user)
        return db_user
    
    def update(self, user_id: int, user_data: UserUpdate) -> Optional[User]:
        """更新用户"""
        db_user = self.get(user_id)
        if not db_user:
            return None
        
        # 更新字段
        update_data = user_data.dict(exclude_unset=True)
        
        # 处理角色更新
        if "role_ids" in update_data:
            role_ids = update_data.pop("role_ids")
            if role_ids is not None:
                roles = self.db.query(Role).filter(Role.id.in_(role_ids)).all()
                db_user.roles = roles
        
        # 更新其他字段
        for field, value in update_data.items():
            setattr(db_user, field, value)
        
        self.db.commit()
        self.db.refresh(db_user)
        return db_user
    
    def delete(self, user_id: int) -> bool:
        """删除用户"""
        db_user = self.get(user_id)
        if not db_user:
            return False
        
        self.db.delete(db_user)
        self.db.commit()
        return True
    
    def activate(self, user_id: int) -> Optional[User]:
        """激活用户"""
        db_user = self.get(user_id)
        if not db_user:
            return None
        
        db_user.is_active = True
        self.db.commit()
        self.db.refresh(db_user)
        return db_user
    
    def deactivate(self, user_id: int) -> Optional[User]:
        """停用用户"""
        db_user = self.get(user_id)
        if not db_user:
            return None
        
        db_user.is_active = False
        self.db.commit()
        self.db.refresh(db_user)
        return db_user
    
    def change_password(self, user_id: int, new_password: str) -> Optional[User]:
        """修改用户密码"""
        db_user = self.get(user_id)
        if not db_user:
            return None
        
        db_user.hashed_password = get_password_hash(new_password)
        self.db.commit()
        self.db.refresh(db_user)
        return db_user
    
    def count(self, is_active: Optional[bool] = None) -> int:
        """统计用户数量"""
        query = self.db.query(User)
        
        if is_active is not None:
            query = query.filter(User.is_active == is_active)
        
        return query.count()
    
    def get_user_permissions(self, user_id: int) -> List[str]:
        """获取用户权限列表"""
        user = self.get(user_id)
        if not user:
            return []
        
        if user.is_superuser:
            # 超级用户拥有所有权限
            from app.models.permission import Permission
            permissions = self.db.query(Permission).filter(Permission.is_active == True).all()
            return [perm.name for perm in permissions]
        
        # 获取用户角色的所有权限
        permissions = set()
        for role in user.roles:
            if role.is_active:
                for perm in role.permissions:
                    if perm.is_active:
                        permissions.add(perm.name)
        
        return list(permissions)